import React, {useState, useEffect} from 'react';
import classnames from 'classnames/bind';
import { Tooltip } from 'antd';

import memo from '../../common/wrapMemo';

import style from './Measure.module.scss';

const {L} = window;
const cb = classnames.bind(style);

let drawLine = null, drawPolygon = null;

const Measure = memo((props) => {
    const {map} = props;

    const [activeLine, setActiveLine] = useState(false);                            // 测线激活状态
    const [activePolygon, setActivePolygon] = useState(false);                      // 测面激活状态
    const [title, setTitle] = useState('');                                   // 测量标题
    const [measureValue, setMeasureValue] = useState('');                        // 测量值

    
    // 测量长度
    useEffect(() => {
        if(!map || !activeLine || drawLine) return;
        if(drawPolygon){
            map.removeLayer(drawPolygon);
            drawPolygon = null;
        }

        if(drawLine){
            map.removeLayer(drawLine);
            drawLine = null;
        }

        map.getContainer().style.cursor = 'crosshair';
        map.doubleClickZoom.disable();
        const shapeOptions = {
            color: '#F54124',
            weight: 3,
            opacity: 0.8,
            fill: false,
            clickable: true
        };

        drawLine = new L.Polyline([], shapeOptions); 
        map.addLayer(drawLine);

        let drawing = false;        // 是否正在绘制
        let drawLinePoints = [];    // 绘制的折线节点集
        let measureResult = 0;      // 测量结果
        var drawMoveLine;           //绘制过程中的折线

        //设置地图的鼠标按下事件
        map.on('click', onClick);
        //设置地图的双击事件
        map.on('dblclick', onDoubleClick);

        //鼠标按下事件
        function onClick(e) {
            drawing = true; //是否正在绘制
            drawLinePoints.push(e.latlng); //绘制的折线的节点集
            //测量结果加上距离上个点的距离
            if(drawLinePoints.length > 1){
                measureResult += e.latlng.distanceTo(drawLinePoints[drawLinePoints.length - 2]);
            }
            //绘制的折线添加进集合
            drawLine.addLatLng(e.latlng); 
            //地图添加鼠标移动事件
            map.on('mousemove', onMove);
        }

        //鼠标移动事件
        function onMove(e) {
            // map.getContainer().style.cursor = 'crosshair';
            if (drawing) { //是否正在绘制
                //将上次的移除
                if (drawMoveLine != undefined && drawMoveLine != null) { //绘制过程中的折线
                    map.removeLayer(drawMoveLine);
                }
                //获取上个点坐标
                var prevPoint = drawLinePoints[drawLinePoints.length - 1];
                //绘制最后一次的折线
                drawMoveLine = new L.Polyline([prevPoint, e.latlng], shapeOptions);
                //添加到地图
                map.addLayer(drawMoveLine);
            }
        }

        //鼠标双击事件
        function onDoubleClick(e) {
            map.getContainer().style.cursor = '';
            /*显示两点距离*/
            //之前的距离加上最后一次的距离
            var distance = measureResult + e.latlng.distanceTo(drawLinePoints[drawLinePoints.length -
                1]);
            setTitle('总距离');
            setMeasureValue((distance / 1000).toFixed(2) + "公里");
            if (drawing) {
                //清除上次的
                if (drawMoveLine != undefined && drawMoveLine != null) {
                    map.removeLayer(drawMoveLine);
                    drawMoveLine = null;
                }
                
                drawLinePoints = [];
                drawing = false;
                //移除事件
                map.off('click', onClick);
                map.off('mousemove', onMove);
                map.off('dblclick', onDoubleClick);
                map.doubleClickZoom.enable();
            }
            setActiveLine(false);
        }
        
    }),[activeLine];

    // 测量面积
    useEffect(() => {
        if(!map || !activePolygon || drawPolygon) return;

        if(drawPolygon){
            map.removeLayer(drawPolygon);
            drawPolygon = null;
        }

        if(drawLine){
            map.removeLayer(drawLine);
            drawLine = null;
        }

        map.getContainer().style.cursor = 'crosshair';
        map.doubleClickZoom.disable();

        let drawing = false;                // 是否正在绘制
        let drawPolygonPoints = [];         // 绘制的面的节点集
        let drawMovePolygon = null;         // 绘制过程中的面


        let shapeOptions = {
            color: '#F54124',
            weight: 3,
            opacity: 0.8,
            fill: true,
            fillColor: null,
            fillOpacity: 0.2,
            clickable: true
        };

        drawPolygon = new L.Polygon([], shapeOptions);
        map.addLayer(drawPolygon);

        // 地图添加鼠标按下事件
        map.on('mousedown', function (e) {
            drawing = true;
            drawPolygonPoints.push(e.latlng);
        });

        // 地图添加鼠标移动事件
        map.on('mousemove', function (e) {
            if (drawing) {
                //清除上次数据
                if (drawMovePolygon != undefined && drawMovePolygon != null) {
                    map.removeLayer(drawMovePolygon);
                }
                drawMovePolygon = new L.Polygon([...drawPolygonPoints, e.latlng], shapeOptions);
                map.addLayer(drawMovePolygon);
            }
        });

        // 地图添加鼠标双击事件
        map.on('dblclick', function (e) {
            map.getContainer().style.cursor = '';
            let tempPoints = [];
            for (let i = 0; i < drawPolygonPoints.length; i++) {
                tempPoints.push(drawPolygonPoints[i]);
                drawPolygon.addLatLng(drawPolygonPoints[i]);
            }
            tempPoints.push(e.latlng);
            //计算面积
            let distance = calcArea(tempPoints);
            setTitle('总面积');
            const value = (distance / 1000000).toFixed(3) + '平方公里';
            setMeasureValue(value);
            if (drawing) {
                if (drawMovePolygon != undefined && drawMovePolygon != null) {
                    map.removeLayer(drawMovePolygon);
                    drawMovePolygon = null;
                }
                
                drawPolygonPoints = [];
                drawing = false;
                //地图移除事件
                map.off('mousedown');
                map.off('mousemove');
                map.off('dblclick');
                map.doubleClickZoom.enable();
            }
            setActivePolygon(false);
        });

        //计算面积
        function calcArea(latLngs) {
            var pointsCount = latLngs.length,
                area = 0.0,
                d2r = Math.PI / 180,
                p1, p2;
            if (pointsCount > 2) {
                for (var i = 0; i < pointsCount; i++) {
                    p1 = latLngs[i];
                    p2 = latLngs[(i + 1) % pointsCount];
                    area += ((p2.lng - p1.lng) * d2r) *
                        (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
                }
                area = area * 6378137.0 * 6378137.0 / 2.0;
            }
            return Math.abs(area);
        }

    }),[activePolygon];

    // 点击测量线
    const lineClick = () => {
        setActivePolygon(false);
        setActiveLine(true);
        remove();
    };

    // 点击测量测量面积
    const areaClick = () => {
        setActivePolygon(true);
        setActiveLine(false);
        remove();
    };

    // 移除
    const remove = () => {
        if(map){
            drawLine && map.removeLayer(drawLine);
            drawPolygon && map.removeLayer(drawPolygon);
            drawLine = null;
            drawPolygon = null;
        }
        setTitle('');
        setMeasureValue('');
    };

    const lineClass = cb({
        line: true,
        lineSelected: activeLine
    });

    const areaClass = cb({
        area: true,
        areaSelected: activePolygon
    });

    return (
        <div className={style.measure}>
            <div className={style.top}>
                <Tooltip placement="bottom" title="测距">
                    <span className={lineClass} onClick={lineClick}>
                        <i className='iconfont icon-measure-distence'></i>
                    </span>
                </Tooltip>
                <Tooltip placement="bottom" title="测面积">
                    <span className={areaClass} onClick={areaClick}>
                        <i className='iconfont icon-measure-area'></i>
                    </span>
                </Tooltip>
            </div>
            {
                measureValue && 
                <div className={style.measureResult} >
                    <div className={style.header}>
                        <span>{title}</span>
                        <i className='iconfont icon-close' onClick={remove}></i>
                    </div>
                    <div className={style.content}>
                        <span className={style.measureNum}>{measureValue}</span>
                    </div>
                </div>
            }
        </div>
    )
});

export default Measure;